import "./index.scss";
import "@rc-component/trigger/assets/index.css";

import {
  JSXElementConstructor,
  ReactElement,
  ReactNode,
  useEffect,
  useRef,
  useState,
} from "react";
import { LFDomRect, LFHTMLDivElement } from "../../types/common";

import Trigger from "@rc-component/trigger";

export interface LfDropdownProps {
  visible?: boolean;
  arrow?: boolean;
  onVisibleChange?: (visible: boolean) => void;
  children: ReactNode | (() => ReactNode | ReactNode[]) | ReactNode[];
  menu?: ReactNode | (() => ReactNode | ReactNode[]) | ReactNode[];
  placement?:
    | "bottomLeft"
    | "bottomRight"
    | "topLeft"
    | "topRight"
    | "top"
    | "bottom"
    | "left"
    | "right";
}

/** 下拉框 */
export const Dropdown = (props: LfDropdownProps) => {
  const {
    children,
    placement = "top",
    visible,
    onVisibleChange,
    menu,
    arrow,
  } = props;
  console.log("lfsz init");

  const targetRef = useRef<LFHTMLDivElement>(null);
  const dropdownRef = useRef<LFHTMLDivElement>(null);
  const [isShow, setIsShow] = useState<boolean>(false);
  const [position, setPosition] = useState<LfDropdownProps["placement"]>("top");
  const computePosition = () => {
    if (targetRef.current) {
      const targetInfo = targetRef.current.getBoundingClientRect() as LFDomRect;

      if (isShow && dropdownRef?.current) {
        let nowPosition = "";
        let newPosition = "";
        let size = "";
        if (placement?.includes("top")) {
          nowPosition = "top";
          newPosition = "bottom";
          size = "offsetHeight";
        } else if (position?.includes("bottom")) {
          nowPosition = "bottom";
          newPosition = "top";
          size = "offsetHeight";
        } else if (position?.includes("left")) {
          nowPosition = "left";
          newPosition = "right";
          size = "offsetWidth";
        } else if (position?.includes("right")) {
          nowPosition = "right";
          newPosition = "left";
          size = "offsetWidth";
        }
        console.log("lfsz", dropdownRef?.current?.[size], targetInfo);

        if (dropdownRef?.current?.[size] + 10 > targetInfo?.[nowPosition]) {
          setPosition(
            placement.replace(
              nowPosition,
              newPosition
            ) as LfDropdownProps["placement"]
          );
        } else {
          setPosition(placement);
        }
      }
    }
  };
  const renderDom = (
    val: LfDropdownProps["children"] | LfDropdownProps["menu"]
  ) => {
    if (Array.isArray(val)) {
      return <>{val.map((item) => item)}</>;
    } else if (typeof val === "function") {
      return <>{val()}</>;
    } else {
      return <>{val}</>;
    }
  };

  const builtinPlacements = {
    left: {
      points: ["cr", "cl"],
      offset: [-10, 0],
    },
    right: {
      points: ["cl", "cr"],
      offset: [10, 0],
    },
    top: {
      points: ["bc", "tc"],
      offset: [0, -10],
    },
    bottom: {
      points: ["tc", "bc"],
      offset: [0, 10],
    },
    topLeft: {
      points: ["bl", "tl"],
      offset: [0, -10],
    },
    topRight: {
      points: ["br", "tr"],
      offset: [0, -10],
    },
    bottomRight: {
      points: ["tr", "br"],
      offset: [0, 10],
    },
    bottomLeft: {
      points: ["tl", "bl"],
      offset: [0, 10],
    },
  };
  const changeHandle = (val: boolean) => {
    if (typeof visible === "boolean") {
      onVisibleChange?.(val);
      return;
    }
    setIsShow(val);
  };
  useEffect(() => {
    if (typeof visible === "boolean") {
      setIsShow(visible);
    }
  }, [visible]);
  useEffect(() => {
    setPosition(placement);
  }, [placement]);
  useEffect(() => {
    window.onscroll = function () {
      computePosition();
    };
  }, [isShow]);
  return (
    <Trigger
      popupPlacement={position}
      //   autoDestroy
      //   stretch="minHeight"
      mouseEnterDelay={0.1}
      mouseLeaveDelay={0.1}
      action="hover"
      builtinPlacements={builtinPlacements}
      arrow={true}
      popup={<div ref={dropdownRef}>{renderDom(menu)}</div>}
      onPopupVisibleChange={changeHandle}
      prefixCls="lf"
      popupVisible={isShow}
    >
      <div className="lf-dropdown" ref={targetRef}>
        {renderDom(children)}
      </div>
    </Trigger>
  );
};
